/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg1ifxClienteTcp;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import pkg1ifxArchivos.caDatosTemplate;
import pkg1ifxArchivos.cifxDatosArchivo;
//import sun.tools.tree.ThisExpression;
import pkg1ifxArchivos.cifxLogs;

/**
 *
 * Clase para conectar un cliente catai CATAI-Cliente, GENVA
 * @author strailaparicio
 */
public class cifxCliente {
    /**
     * Variables privadas de la clase Cliente
     */
    private Socket socket= new Socket();
    private boolean bconectado=false;
    private int npuerto=9623;
    private String sipservidor="127.0.0.1";
    private cifxDatosArchivo odarchivo = new cifxDatosArchivo();
    private int ntamanoenvio=1024; //Variable con el tamaño de encvio de datos byte 
    private PrintWriter pout = null;
    private BufferedReader bin =null;
    private cifxLogs olog = new cifxLogs();
    private String stmpmsj="";
    private String sultimarespuesta="";
    private String scadenaperdida="";
    private int ntimeout=0;
    private String sENTER= System.getProperty("line.separator");
    private String ssoservidor="UNIX";
    //FENIX
    //private caDatosTemplate odatostemplate = new caDatosTemplate();
    
    /***
     * 
     * @param direccion
     * @param puerto
     * @param timeout 
     */
    public cifxCliente(String direccion,int puerto, int timeout)
    {
        npuerto=puerto;
        sipservidor= direccion;
        olog.setSalConsola(true);
        olog.setSalLog(true);
        SecurityManager sm = System.getSecurityManager();
        
        olog.outMensaje("cifxCliente: INICIO Conexion ("+sipservidor+":"+String.valueOf(npuerto)+")");
        try {
            socket = new Socket();
            SocketAddress osa= new InetSocketAddress(sipservidor, npuerto);
            ntimeout=timeout;
            socket.connect(osa, ntimeout);
            bconectado=socket.isConnected();
            //socket.setSoTimeout(3000);
            //socket.co
            if(!bconectado)
            {
                olog.outMensaje("cifxCliente: NO CONECTADO ("+direccion+":"+String.valueOf(puerto)+")");
                return;
            }
            
            pout = new PrintWriter(socket.getOutputStream(), true);
            bin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            olog.outMensaje("cifxCliente: Conectado ("+direccion+":"+String.valueOf(puerto)+")");
            
            stmpmsj= bin.readLine();
            olog.outMensaje("cifxCliente: Conectado en un servidor ("+stmpmsj+")");
            
            
            
            
        }catch(SocketTimeoutException tex)
        {
            olog.outMensaje("cifxCliente.cifxCliente: Time out :"+tex.toString());

        } 
        catch (UnknownHostException ex) {
            //Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cifxCliente.cifxCliente: UnknownHostException ("+ex.toString()+")");
        } catch (IOException ex) {
            //Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cifxCliente.cifxCliente: IOException ("+ex.toString()+")");
        }
    }
    
    /**
     * 
     * @param direccion, La direccion IP donde se va a conectar el cliente IP V4
     * @param puerto , El puesto donde escucha al servidor por defecto para INFOGEX 9623
     */
    public cifxCliente(String direccion,int puerto)
    {
        npuerto=puerto;
        sipservidor= direccion;
        olog.setSalConsola(true);
        olog.setSalLog(true);
        SecurityManager sm = System.getSecurityManager();
        
        olog.outMensaje("cifxCliente: INICIO Conexion ("+sipservidor+":"+String.valueOf(npuerto)+")");
        try {
//            try
//            {
//                sm.checkConnect(sipservidor, npuerto);
//            }catch(SecurityException se)
//            {
//               olog.outMensaje("cifxCliente: No se puede CONECTAR ("+direccion+":"+String.valueOf(puerto)+")");
//               return;
//            }
            socket = new Socket();
            SocketAddress osa= new InetSocketAddress(sipservidor, npuerto);
            socket.connect(osa, ntimeout);
            bconectado=socket.isConnected();
            //socket.setSoTimeout(3000);
            //socket.co
            if(!bconectado)
            {
                olog.outMensaje("cifxCliente: NO CONECTADO ("+direccion+":"+String.valueOf(puerto)+")");
                return;
            }
            
            pout = new PrintWriter(socket.getOutputStream(), true);
            bin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            olog.outMensaje("cifxCliente: Conectado ("+direccion+":"+String.valueOf(puerto)+")");
            
            stmpmsj= bin.readLine();
            olog.outMensaje("cifxCliente: Conectado en un servidor ("+stmpmsj+")");
            
            
            
            
        }catch(SocketTimeoutException tex)
        {
            olog.outMensaje("cifxCliente.cifxCliente: Time out :"+tex.toString());

        } 
        catch (UnknownHostException ex) {
            //Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cifxCliente.cifxCliente: UnknownHostException ("+ex.toString()+")");
        } catch (IOException ex) {
            //Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cifxCliente.cifxCliente: IOException ("+ex.toString()+")");
        }
    }
    public boolean estaConectado()
    {
        return socket.isConnected();
    }
    
    public void Desconectar()
    {
        if(!bconectado)
            return;
        try {
            pout.println(":)");
//            bin.close();
//            pout.close();
//            socket.close();
        } catch (Exception ex) {
            //Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("Desconectar(): ERROR:" + ex.getMessage());
        }
        
    }
    public void setTimeOut(int dato)
    {
        ntimeout=dato;
    }
    /**
     * 
     * @return 
     */
    public int renombrarArchivo(String pathorigen, String pathdestino)
    {
        if(!bconectado)
            return -1;
        
        olog.outMensaje("renombrarArchivo(): Renombrando :"+pathorigen+" "+pathdestino);
        
        if(ssoservidor.contains("UNIX"))
        {
            
            return EnviarCmd("mv "+pathorigen+" "+pathdestino);
        }
        else //Es un windows
        {
            
            return EnviarCmd("rename "+pathorigen+" "+pathdestino);
        }
    }
    /**
     * crea un directorio en el servidor en la ruta especificada
     * @param pathdirectorio
     * @return 
     */
    public int crearDirectorio(String pathdirectorio)
    {
        if(!bconectado)
            return -1;
        
        olog.outMensaje("borrarArchivos(): Creando directorio :"+pathdirectorio);
        
        if(ssoservidor.contains("UNIX"))
        {
            
            return EnviarCmd("mkdir "+pathdirectorio);
        }
        else //Es un windows
        {
            
            return EnviarCmd("mkdir "+pathdirectorio);
        }  
    }
    /**
     * Esta funcion permite borrar archivos en el servidor
     * Independiente del SO, Windows o Unix
     * 
     * @param patharchivo, puede ser la ruta y el nombre del archivo a borrar o se puede 
     *                     usar el comodin *
     * @return,
     * -1, exite un error
     * >0, ha terminado correctamente la ejecucion
     */
    public int borrarArchivos(String patharchivo)
    {
        if(!bconectado)
            return -1;
        
        olog.outMensaje("borrarArchivos(): borrando :"+patharchivo);
        
        if(ssoservidor.contains("UNIX"))
        {
            
            return EnviarCmd("rm "+patharchivo);
        }
        else //Es un windows
        {
            
            return EnviarCmd("del "+patharchivo);
        }
        

    }
    /**
     * Ejecuta un comando en el servidor
     * @param scmd
     * @return 
     */
    public int EnviarCmd(String scmd)
    {
        if(!bconectado)
            return -1;
        
        String srespuesta="";
        int nres;
        olog.outMensaje("EnviarCmd(): Ejecutando CMD:"+scmd);
        pout.println("IFX-Cmd "+scmd);
        sultimarespuesta="";
        //byte[] buffer=new byte[2048];
        String stmp="";
        //InputStream sis;
        
        try {
            
            olog.outMensaje("cifxCliente.EnviarCmd(): Esperando respuesta:");
            //while((nres=bin.read())!=-1)
            do
            {
                    sultimarespuesta+=bin.readLine()+"\n";
                
            }while(bin.ready());
            
            olog.outMensaje("cifxCliente.EnviarCmd(): Respuesta:"+sultimarespuesta);
            
        }catch(SocketTimeoutException tex)
        {
            olog.outMensaje("cifxCliente.EnviarCmd(): Time out :"+tex.toString());
            return -1;

        }
        catch (IOException ex) {
            //Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cifxCliente.EnviarCmd(): IOException"+ex.toString());
            return -1;
        }
        return 1;
    }
    public String getUltimaRespuesta()
    {
        return sultimarespuesta;
    }
    /**
     * Retorna la informacion del archivo tamaño
     * @param scmd
     * @return 
     */
    public long informacionArchivo(String patharchivo)
    {
        if(!bconectado)
            return -1;
        
        long nrespuesta=-1;
        int nres;
        olog.outMensaje("cifxCliente.IFX-informacionArchivo(): Ejecutando InfArchi:"+patharchivo);
        pout.println("IFX-InfFile "+patharchivo);
        sultimarespuesta="";
        //byte[] buffer=new byte[2048];
        //String stmp="";
        //InputStream sis;
        
        try {
            
            olog.outMensaje("cifxCliente.informacionArchivo(): Esperando respuesta:");
            //while((nres=bin.read())!=-1)
            do
            {
                    sultimarespuesta+=bin.readLine();
                
            }while(bin.ready());
            
            olog.outMensaje("cifxCliente.informacionArchivo(): Respuesta:"+sultimarespuesta);
            nrespuesta=Long.parseLong(sultimarespuesta);
            
        }catch(SocketTimeoutException tex)
        {
            olog.outMensaje("cifxCliente.informacionArchivo(): Time out :"+tex.getMessage());
            return -1;

        }
        catch (IOException ex) {
            //Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cifxCliente.informacionArchivo(): IOException"+ex.getMessage());
            return -1;
        }
        return nrespuesta;
    }
    
    /**
     * 
     * @param smensaje 
     */
    public void EnviaMensaje(String smensaje)
    {
        
    }
    /**
     * Funcion para quitar una palabra al principio de una frase
     * @param sfrase, la frase que contiene la palabra a quitar
     * @param spalabra, la palabra que se quitara de la frase
     * @return 
     */
    private String quitarPalabra(String sfrase, String spalabra)
    {
        String ssalida="";
        int nstart = sfrase.indexOf(spalabra)+spalabra.length();
        ssalida = sfrase.substring(nstart);
        return ssalida;

    }
    
    public int putASCII(String sorigen,String sdestino)
    {
        int nrsalida=-1;
        if(!bconectado)
            return -1;
        OutputStream sout;
        //InputStream fin;
        RandomAccessFile rfin;
        BufferedReader brin;
        String sentrada="";
        long ntotalenviado=0;
        byte[] buff= new byte[ntamanoenvio];
        int len;
        long ninicioread = 0;
        odarchivo.setOrigen(sorigen);
        odarchivo.setDestino(sdestino);
        odarchivo.setTamanoTransmit(ntamanoenvio);
        
       
      
        olog.outMensaje("putASCII: Cargando el File java: "+odarchivo.getOrigen());
        //olog.outMensaje("cifxCliente: Conectado ("+direccion+":"+String.valueOf(puerto)+")");
        File forigen = new File(odarchivo.getOrigen());

        
        if(forigen.exists())
        {
            //if()
            odarchivo.setTamanoArchivo(forigen.length());
 
            try {
                
                //fin = new FileInputStream(forigen);
                FileReader frd = new FileReader(forigen);//Para leer el archivo en texto
                BufferedReader rtxt = new BufferedReader(frd);
                olog.outMensaje("putASCII: Abriendo archivo TEXTO :");
                //rfin = new RandomAccessFile(forigen, "rw");
                sout = socket.getOutputStream();
                brin = bin;//new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter lout = new PrintWriter(socket.getOutputStream(), true);
                
                //sout.write(("IFX-putASCII "+odarchivo.aCadena()+"\n").getBytes());
                lout.println("IFX-putASCII "+odarchivo.aCadena());
                //sentrada=brin.readLine();
                sentrada=brin.readLine();
                if(sentrada.contains("IFX-putASCII existe"))
                {
                    olog.outMensaje("putASCII: Ya existe en el servidor el archivo: "+odarchivo.getDestino());

                    ninicioread=odarchivo.getTamanoArchivo();
                    //return;
                }
                else if(sentrada.contains("IFX-putASCII tamano:"))
                {
                    ninicioread= Long.parseLong(quitarPalabra(sentrada,"IFX-putASCII tamano:"));
                }
 
                if(odarchivo.getTamanoArchivo()>0)
                {
                    //
                    olog.outMensaje("putASCII: INICIO Envio archivo de tamaño :"+odarchivo.getTamanoArchivo());
                    olog.outMensaje("putASCII: El envio inicia a partir de :"+ (ninicioread));

                    //rfin.seek(ninicioread);
                    //Variables para UTF-8
                    String stmp="";


                    while((stmp = rtxt.readLine())!=null)
                    {
                        //Aqui convierto la cadena a UTF-8 antes de enviarlos
                        //stmp= new  String(buff,"UTF8");
                        len =stmp.getBytes("UTF8").length; 
                        //sout.write(stmp.getBytes("UTF8"));
                        lout.println(stmp);
                        //sout.write(buff,0,len);
                        ntotalenviado+= len;
                        lout.flush();
                        //System.out.print("*");
                    }
                    
                    //YATA
                    lout.println("IFX-putASCII TATAA");

                    //"IFX-Put TERMENI"
                    sentrada=brin.readLine();
                    if(sentrada.equals("IFX-putASCII TERMENI"))
                    {
                        lout.flush();
                        olog.outMensaje("leer_BytesEnviarASCII: TERMINO - Total enviado ->"+ntotalenviado);

                        rtxt.close();
                    }
                    else
                        olog.outMensaje("leer_BytesEnviarASCII: ERROR - Total enviado ->"+ntotalenviado);

                }
                nrsalida=1;
                
            }catch(SocketTimeoutException tex)
            {
                olog.outMensaje("cifxCliente.leer_BytesEnviarASCII(): Time out :"+tex.toString());
                nrsalida=-1;

            } 
                    
            catch (FileNotFoundException ex) {
                Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
                olog.outMensaje("cifxCliente.leer_BytesEnviarASCII: FileNotFoundException"+ex.toString());
                nrsalida=-1;
            }
            catch (IOException ex) {
                Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
                olog.outMensaje("cifxCliente.leer_BytesEnviarASCII: IOException"+ex.toString());
                nrsalida=-1;
            }
            
            
            
        }
        else
        {
            olog.outMensaje("leer_BytesEnviarASCII: Archivo no existe :"+odarchivo.getOrigen());
            nrsalida=-1;
        }
        return nrsalida;
        
    }
    /*
     * 
     */
    public int leer_BytesEnviarASCII(String sorigen,String sdestino)
    {
        //Hoy 20 julio de 2011, haciendo arreglo para garantizar unicode UTF-8
        int nrsalida=-1;
        if(!bconectado)
            return -1;
        OutputStream sout;
        //InputStream fin;
        RandomAccessFile rfin;
        BufferedReader brin;
        String sentrada="";
        long ntotalenviado=0;
        byte[] buff= new byte[ntamanoenvio];
        int len;
        long ninicioread = 0;
        odarchivo.setOrigen(sorigen);
        odarchivo.setDestino(sdestino);
        odarchivo.setTamanoTransmit(ntamanoenvio);
       
      
        olog.outMensaje("leer_BytesEnviarASCII: Cargando el File java: "+odarchivo.getOrigen());
        //olog.outMensaje("cifxCliente: Conectado ("+direccion+":"+String.valueOf(puerto)+")");
        File forigen = new File(odarchivo.getOrigen());
      
        
        if(forigen.exists())
        {
            //if()
            odarchivo.setTamanoArchivo(forigen.length());
 
            try {
                
                //fin = new FileInputStream(forigen);
                olog.outMensaje("leer_BytesEnviarASCII: Abriendo archivo random :");
                rfin = new RandomAccessFile(forigen, "rw");
                sout = socket.getOutputStream();
                brin = bin;//new BufferedReader(new InputStreamReader(socket.getInputStream()));
                
                sout.write(("IFX-putASCII "+odarchivo.aCadena()+"\n").getBytes());
                //sentrada=brin.readLine();
                sentrada=brin.readLine();
                if(sentrada.contains("IFX-putASCII existe"))
                {
                    olog.outMensaje("leer_BytesEnviarASCII: Ya existe en el servidor el archivo: "+odarchivo.getDestino());

                    ninicioread=odarchivo.getTamanoArchivo();
                    //return;
                }
                else if(sentrada.contains("IFX-putASCII tamano:"))
                {
                    ninicioread= Long.parseLong(quitarPalabra(sentrada,"IFX-putASCII tamano:"));
                }
 
                if(odarchivo.getTamanoArchivo()>0)
                {
                    //
                    olog.outMensaje("leer_BytesEnviarASCII: INICIO Envio archivo de tamaño :"+odarchivo.getTamanoArchivo());
                    olog.outMensaje("leer_BytesEnviarASCII: El envio inicia a partir de :"+ (ninicioread));

                    rfin.seek(ninicioread);
                    //Variables para UTF-8
                    String stmp="";


                    while((len = rfin.read(buff))>0)
                    {
                        //Aqui convierto la cadena a UTF-8 antes de enviarlos
                        stmp= new  String(buff,"UTF8");
                        sout.write(stmp.getBytes("UTF8"),0,len);
                        //sout.write(buff,0,len);
                        ntotalenviado+= len;
                        sout.flush();
                        //System.out.print("*");
                    }

                    //"IFX-Put TERMENI"
                    sentrada=brin.readLine();
                    if(sentrada.equals("IFX-putASCII TERMENI"))
                    {
                        sout.flush();
                        olog.outMensaje("leer_BytesEnviarASCII: TERMINO - Total enviado ->"+ntotalenviado);

                        rfin.close();
                    }
                    else
                        olog.outMensaje("leer_BytesEnviarASCII: ERROR - Total enviado ->"+ntotalenviado);

                }
                nrsalida=1;
                
            }catch(SocketTimeoutException tex)
            {
                olog.outMensaje("cifxCliente.leer_BytesEnviarASCII(): Time out :"+tex.toString());
                nrsalida=-1;

            } 
                    
            catch (FileNotFoundException ex) {
                Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
                olog.outMensaje("cifxCliente.leer_BytesEnviarASCII: FileNotFoundException"+ex.toString());
                nrsalida=-1;
            }
            catch (IOException ex) {
                Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
                olog.outMensaje("cifxCliente.leer_BytesEnviarASCII: IOException"+ex.toString());
                nrsalida=-1;
            }
            
            
            
        }
        else
        {
            olog.outMensaje("leer_BytesEnviarASCII: Archivo no existe :"+odarchivo.getOrigen());
            nrsalida=-1;
        }
        return nrsalida;
        
    }
    /**
     * Esta funcion tiene control de flujo de datos esperando MSJ del
     * servidor para indicar que ya se enviaron los datos
     * "IFX-Put TERMENI"
     * @param sorigen
     * @param sdestino 
     */
    public int leer_BytesEnviar(String sorigen,String sdestino)
    {
        //Hoy 20 julio de 2011, haciendo arreglo para garantizar unicode UTF-8
        int nrsalida=-1;
        if(!bconectado)
            return -1;
        OutputStream sout;
        //InputStream fin;
        RandomAccessFile rfin;
        BufferedReader brin;
        String sentrada="";
        long ntotalenviado=0;
        byte[] buff= new byte[ntamanoenvio];
        int len;
        long ninicioread = 0;
        odarchivo.setOrigen(sorigen);
        odarchivo.setDestino(sdestino);
        odarchivo.setTamanoTransmit(ntamanoenvio);
       
      
        olog.outMensaje("leer_BytesEnviar: Cargando el File java: "+odarchivo.getOrigen());
        //olog.outMensaje("cifxCliente: Conectado ("+direccion+":"+String.valueOf(puerto)+")");
        File forigen = new File(odarchivo.getOrigen());
      
        
        //if(forigen.exists() && forigen.length()>0)
        if(forigen.exists())    
        {
            //if()
            odarchivo.setTamanoArchivo(forigen.length());
 
            try {
                
                //fin = new FileInputStream(forigen);
                olog.outMensaje("leer_BytesEnviar: Abriendo archivo random :");
                rfin = new RandomAccessFile(forigen, "rw");
                sout = socket.getOutputStream();
                brin = bin;//new BufferedReader(new InputStreamReader(socket.getInputStream()));
                
                sout.write(("IFX-Put "+odarchivo.aCadena()+"\n").getBytes());
                //sentrada=brin.readLine();
                sentrada=brin.readLine();
                if(sentrada.contains("IFX-Put existe"))
                {
                    olog.outMensaje("leer_BytesEnviar: Ya existe en el servidor el archivo: "+odarchivo.getDestino());

                    ninicioread=odarchivo.getTamanoArchivo();
                    //return;
                }
                else if(sentrada.contains("IFX-Put tamano:"))
                {
                    ninicioread= Long.parseLong(quitarPalabra(sentrada,"IFX-Put tamano:"));
                }
                
                if(odarchivo.getTamanoArchivo()>0)
                {
 
                    //
                    olog.outMensaje("leer_BytesEnviar: INICIO Envio archivo de tamaño :"+odarchivo.getTamanoArchivo());
                    olog.outMensaje("leer_BytesEnviar: El envio inicia a partir de :"+ (ninicioread));

                    rfin.seek(ninicioread);
                    //Variables para UTF-8
                    String stmp="";


                    while((len = rfin.read(buff))>0)
                    {
                        //Aqui convierto la cadena a UTF-8 antes de enviarlos
                        //stmp= new  String(buff,"UTF8");
                        sout.write(buff,0,len);
                        //sout.write(buff,0,len);
                        ntotalenviado+= len;
                        sout.flush();
                        //System.out.print("*");
                    }

                    //"IFX-Put TERMENI"
                    sentrada=brin.readLine();
                    if(sentrada.equals("IFX-Put TERMENI"))
                    {
                        sout.flush();
                        olog.outMensaje("leer_BytesEnviar: TERMINO - Total enviado ->"+ntotalenviado);

                        rfin.close();
                    }
                    else
                        olog.outMensaje("leer_BytesEnviar: ERROR - Total enviado ->"+ntotalenviado);
                    
                }
                nrsalida=1;
                
            }catch(SocketTimeoutException tex)
            {
                olog.outMensaje("cifxCliente.leer_BytesEnviar(): Time out :"+tex.toString());
                nrsalida=-1;

            } 
                    
            catch (FileNotFoundException ex) {
                Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
                olog.outMensaje("cifxCliente.leer_BytesEnviar: FileNotFoundException"+ex.toString());
                nrsalida=-1;
            }
            catch (IOException ex) {
                Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
                olog.outMensaje("cifxCliente.leer_BytesEnviar: IOException"+ex.toString());
                nrsalida=-1;
            }
            
            
            
        }
        else
        {
            olog.outMensaje("leer_BytesEnviar: Archivo no existe :"+odarchivo.getOrigen());
            nrsalida=-1;
        }
        return nrsalida;
        
    }
    /**
     * Funciona para leer el archivo del disco y enviarlo al servidor
     * @param snombrearchivo, nombreArchivo
     * @param spathdestino , laruta donde se deben guardar los datos en el destino
     * @param spathorigen , El origen del archivo 
     */
    public void _leerEnviarBytes(String sorigen,String sdestino)
    {
        if(!bconectado)
            return;
        OutputStream sout;
        //InputStream fin;
        RandomAccessFile rfin;
        BufferedReader brin;
        String sentrada="";
        long ntotalenviado=0;
        byte[] buff= new byte[ntamanoenvio];
        int len;
        long ninicioread = 0;
        odarchivo.setOrigen(sorigen);
        odarchivo.setDestino(sdestino);
        odarchivo.setTamanoTransmit(ntamanoenvio);
       
      
        olog.outMensaje("leerEnviarBytes: Cargando el File java: "+odarchivo.getOrigen());
        //olog.outMensaje("cifxCliente: Conectado ("+direccion+":"+String.valueOf(puerto)+")");
        File forigen = new File(odarchivo.getOrigen());
      
        
        if(forigen.exists())
        {
            odarchivo.setTamanoArchivo(forigen.length());
            try {
                
                //fin = new FileInputStream(forigen);
                olog.outMensaje("leerEnviarBytes: Abriendo archivo random :");
                rfin = new RandomAccessFile(forigen, "rw");
                sout = socket.getOutputStream();
                brin = bin;//new BufferedReader(new InputStreamReader(socket.getInputStream()));
                
                
                //pout.write("IFX-Put "+odarchivo.aCadena());
                //pout.println("IFX-Put "+odarchivo.aCadena()+"\n");
                sout.write(("IFX-Put "+odarchivo.aCadena()+"\n").getBytes());
                //sentrada=brin.readLine();
                sentrada=brin.readLine();
                if(sentrada.contains("IFX-Put existe"))
                {
                    olog.outMensaje("leerEnviarBytes: Ya existe en el servidor el archivo: "+odarchivo.getDestino());
                    ninicioread=odarchivo.getTamanoArchivo();
                    return;
                }
                else if(sentrada.contains("IFX-Put tamano:"))
                {
                    ninicioread= Long.parseLong(quitarPalabra(sentrada,"IFX-Put tamano:"));
                }
 
                if(odarchivo.getTamanoArchivo()>0)
                {
                    //
                    olog.outMensaje("leerEnviarBytes: INICIO Envio archivo de tamaño :"+odarchivo.getTamanoArchivo());
                    olog.outMensaje("leerEnviarBytes: El envio inicia a partir de :"+ (ninicioread));

                    rfin.seek(ninicioread);

                    while((len = rfin.read(buff))>0)
                    {
                        sout.write(buff,0,len);
                        ntotalenviado+= len;
                        sout.flush();
                        //System.out.print("*");
                    }

                    sout.flush();
                    olog.outMensaje("leerEnviarBytes: TERMINO - Total enviado ->"+ntotalenviado);
                    rfin.close();
                    //
                }
            } 
            catch (FileNotFoundException ex) {
                Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
                olog.outMensaje("leerEnviarBytes: FileNotFoundException"+ex.toString());
            }
            catch (IOException ex) {
                Logger.getLogger(cifxCliente.class.getName()).log(Level.SEVERE, null, ex);
                olog.outMensaje("leerEnviarBytes: IOException"+ex.toString());
            }
            
            
            
        }
        
        
        
    }
     /**
     * 
     * @param datos
     * @return , direfencia de los bytes que se quitan de la cadena
     */
    private int quitarCRNL(byte[] datos)
    {
        int nnuevotam=0;
        try {
            String soldcadena = new String(datos,"UTF8");
            String snewcadena = new String(datos,"UTF8");
            
            soldcadena=soldcadena.replaceAll("\r\n", "\n");
            
            nnuevotam= (snewcadena.length()-soldcadena.length());
            return nnuevotam;
            
        } catch (UnsupportedEncodingException ex) {
            
            olog.outMensaje("cIfxClientesCon.quitarCRNL(): ERROR:"+ex.toString());
            return 0;
        }
        
        
    }

    /**
     * ASCII
     * @param odarchivo
     * @return 
     */
    public int leerGuardarBytesASCII(cifxDatosArchivo odarchivo) 
    {
        int nretorno=-1;
        if(!bconectado)
            return nretorno;
        Socket puerto=socket;
        InputStream sis;
        String stmp;
        try {
                sis = puerto.getInputStream();

                PrintWriter lout = new PrintWriter(puerto.getOutputStream(), true);
                BufferedReader lin = new BufferedReader(new InputStreamReader(puerto.getInputStream()));

                byte[] buffer=new byte[ntamanoenvio];
                int nread=0;
                long ntotalleido=0;
                OutputStream fout = null;
                //String sSalir="";
                //Manejo de archivo en disco
                
                lout.println("IFX-getASCII "+odarchivo.getOrigen());
                stmp=lin.readLine();
                stmp=quitarPalabra(stmp,"IFX-getASCII ");
                
                odarchivo.ConvCad(stmp);
                
                File fdestino = new File(odarchivo.getDestino());
                if(fdestino.exists())
                {
                        //Si el archivo existe abrirlo para agregar lo que falta
                        //si el tamaño del archivo es igual al que se va a transmitir?
                        //salir archivo ya existe y no se hace nada
                    if(fdestino.length()>=odarchivo.getTamanoArchivo())
                    {
                        lout.println("IFX-getASCII existe");
                        olog.outMensaje("cifxCliente.leerGuardarBytes(): YA EXISTE el archivo: "+odarchivo.getDestino());
                        //return;
                    }
                    olog.outMensaje("cifxCliente.leerGuardarBytes(): YA EXISTE el archivo pero incompleto: "+odarchivo.getDestino());
                    olog.outMensaje("cifxCliente.leerGuardarBytes():  El tamaño actual es: "+fdestino.length());

                    fout = new FileOutputStream(fdestino,true);
                    lout.println("IFX-getASCII tamano:"+fdestino.length());
                    ntotalleido=fdestino.length();
                    //fdestino.

                }
                else
                {
                     fout = new FileOutputStream(fdestino,true);
                     lout.println("IFX-getASCII tamano:0");

                }
                //OutputStream fout = new FileOutputStream(fdestino,true);

                olog.outMensaje("cifxCliente.leerGuardarBytes():  Inicio guardar archivo :"+odarchivo.getDestino());
                olog.outMensaje("cifxCliente.leerGuardarBytes():  Tamaño archivo ->"+odarchivo.getTamanoArchivo());
                int nlen=0;
                
                //Strail UNICODE UTF-8
                //String stmp="";

                while(((nread = sis.read(buffer))>0))
                //while(((nread = sis.read(buffer))!=-1))
                {
                    ntotalleido+=nread;
                    if(ntotalleido>odarchivo.getTamanoArchivo())
                    {
                        nread=nread-(int)(ntotalleido-odarchivo.getTamanoArchivo());
                        int ndiff=quitarCRNL(buffer);
                        stmp=new String(buffer,"UTF8");
                        //Esto es una prueba
                        stmp=stmp.replaceAll("\r\n", "\n");
                        //nread=stmp.getBytes("UTF8").length;
                        if(ndiff>0)
                            nread=nread-ndiff;
                        fout.write(stmp.getBytes("UTF8"),0,nread);
                        scadenaperdida=stmp.substring(nread+1);
                        //fout.write(buffer,0,nread);
                        fout.write(stmp.getBytes("UTF8"),0,nread);
                        //fout.write(stmp.getBytes("UTF8"));
                        fout.flush();
                        lout.println("IFX-getASCII TERMENI");
                        
                        break;
                    }
                    else if(ntotalleido==odarchivo.getTamanoArchivo())
                    {
                        int ndiff=quitarCRNL(buffer);
                        stmp=new String(buffer,"UTF8");
                        //Esto es una prueba
                        stmp=stmp.replaceAll("\r\n", "\n");
                        //nread=stmp.getBytes("UTF8").length;
                        if(ndiff>0)
                            nread=nread-ndiff;
                        fout.write(stmp.getBytes("UTF8"),0,nread);
                        fout.flush();
                        lout.println("IFX-getASCII TERMENI");
                        break;
                    }
                    else
                    {
                        int ndiff=quitarCRNL(buffer);
                        stmp=new String(buffer,"UTF8");
                        //Esto es una prueba
                        stmp=stmp.replaceAll("\r\n", "\n");
                        //nread=stmp.getBytes("UTF8").length;
                        if(ndiff>0)
                            nread=nread-ndiff;
                        fout.write(stmp.getBytes("UTF8"),0,nread);
                    }

                }

                fout.flush();

                olog.outMensaje("cifxCliente.leerGuardarBytes():  FIN LEER Total Leido ->"+ntotalleido);
                olog.outMensaje("cifxCliente.leerGuardarBytes():  TAMAÑO Archivo Total Leido ->"+odarchivo.getTamanoArchivo());
                //System.out.println("leerGuardarBytes - Termina guardar archivo");

                //sis.close();
                //lout.close();
                //lin.close();
                fout.close();
                nretorno=1;
        } catch(SocketTimeoutException tex)
        {
            olog.outMensaje("cifxCliente.leerGuardarBytes(): Time out :"+tex.toString());
            return -1;
        } 
        catch (IOException ex) {
            //Logger.getLogger(cIfxClientesCon.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cifxCliente.leerGuardarBytes(): ERROR:"+ex.toString());
            return -1;
        }
        return nretorno;
    }
    /**
     * Esta fucion mueve un archivo a otro nombre
     * archivo.ext# donde # inicia en 1 hasta n
     * @param paharchivo 
     */
    public void moverArchivoViejo(String paharchivo)
    {
        File oldfile = new File(paharchivo);
        File newfile = new File(paharchivo);
        int nconse=1;
        while(newfile.exists())
        {
            newfile = new File(paharchivo+nconse);
            nconse++;
            
        }
        
        
        oldfile.renameTo(newfile);
        
    }
    /**
     * 
     * @param odarchivo
     * @return 
     */
    public int leerGuardarBytes(cifxDatosArchivo odarchivo) 
    {
        int nretorno=-1;
        if(!bconectado)
            return nretorno;
        Socket puerto=socket;
        InputStream sis;
        String stmp;
        try {
                sis = puerto.getInputStream();

                PrintWriter lout = new PrintWriter(puerto.getOutputStream(), true);
                BufferedReader lin = new BufferedReader(new InputStreamReader(puerto.getInputStream()));

                byte[] buffer=new byte[ntamanoenvio];
                int nread=0;
                long ntotalleido=0;
                OutputStream fout = null;
                //String sSalir="";
                //Manejo de archivo en disco
                
                lout.println("IFX-Get "+odarchivo.getOrigen());
                stmp=lin.readLine();
                //El servidor envia un IFX-Get NO EXISTE, para indicar que no existe el archivo
                if(stmp.contains("IFX-Get NOEXISTE"))
                {
                    olog.outMensaje("cifxCliente.leerGuardarBytes(): El archivo NO EXISTE EN EL SERVIDOR ");
                    return -1;
                }
                
                stmp=quitarPalabra(stmp,"IFX-Get ");
                
                odarchivo.ConvCad(stmp);
                
                File fdestino = new File(odarchivo.getDestino());
                if(fdestino.exists())
                {
                        //Si el archivo existe abrirlo para agregar lo que falta
                        //si el tamaño del archivo es igual al que se va a transmitir?
                        //salir archivo ya existe y no se hace nada
                    if(fdestino.length()>=odarchivo.getTamanoArchivo())
                    {
                        //Aqui elimino este punto solo intereza el nuevo tamaño
                        //lout.println("IFX-Get existe");
                        
                        olog.outMensaje("cifxCliente.leerGuardarBytes(): YA EXISTE el archivo: "+odarchivo.getDestino());
                        //Si el archivo existe y es del mismo tamaño o mayor renombrar el viejo
                        //y crear uno nuevo con los datos que vienen
                        //
                        moverArchivoViejo(odarchivo.getDestino());
                        fdestino = new File(odarchivo.getDestino());
                        //return;
                    }
                    olog.outMensaje("cifxCliente.leerGuardarBytes(): YA EXISTE el archivo pero incompleto: "+odarchivo.getDestino());
                    olog.outMensaje("cifxCliente.leerGuardarBytes():  El tamaño actual es: "+fdestino.length());

                    fout = new FileOutputStream(fdestino,true);
                    lout.println("IFX-Get tamano:"+fdestino.length());
                    ntotalleido=fdestino.length();
                    //fdestino.

                }
                else
                {
                     fout = new FileOutputStream(fdestino,true);
                     lout.println("IFX-Get tamano:0");

                }
                //Valido que el tamaño del archivo sea mayor de 0 paraguardar d elo contrario no hago nada
                if(odarchivo.getTamanoArchivo()>0)
                {
                    //OutputStream fout = new FileOutputStream(fdestino,true);

                    olog.outMensaje("cifxCliente.leerGuardarBytes():  Inicio guardar archivo :"+odarchivo.getDestino());
                    olog.outMensaje("cifxCliente.leerGuardarBytes():  Tamaño archivo ->"+odarchivo.getTamanoArchivo());
                    int nlen=0;

                    //Strail UNICODE UTF-8
                    //String stmp="";


                    while(((nread = sis.read(buffer))>=0))
                    //while(((nread = sis.read(buffer))!=-1))
                    //while(sis.available()>0)
                    {
                        //nread = sis.read(buffer);
                        ntotalleido+=nread;
                        if(ntotalleido>odarchivo.getTamanoArchivo())
                        {
                            nread=nread-(int)(ntotalleido-odarchivo.getTamanoArchivo());
                            ///stmp=new String(buffer,"UTF8");
                            fout.write(buffer,0,nread);
                            scadenaperdida=stmp.substring(nread+1);
                            fout.flush();
                            lout.println("IFX-Get TERMENI");

                            break;
                        }
                        else if(ntotalleido==odarchivo.getTamanoArchivo())
                        {
                            //stmp=new String(buffer,"UTF8");
                            fout.write(buffer,0,nread);
                            fout.flush();
                            lout.println("IFX-Get TERMENI");
                            break;
                        }
                        else
                        {
                            //stmp=new String(buffer,"UTF8");
                            fout.write(buffer,0,nread);
                        }

                    }

                    fout.flush();

                    olog.outMensaje("cifxCliente.leerGuardarBytes():  FIN LEER Total Leido ->"+ntotalleido);
                    olog.outMensaje("cifxCliente.leerGuardarBytes():  TAMAÑO Archivo Total Leido ->"+odarchivo.getTamanoArchivo());
                    //System.out.println("leerGuardarBytes - Termina guardar archivo");

                    //sis.close();
                    //lout.close();
                    //lin.close();
                }
                fout.close();
                nretorno=1;
        } catch(SocketTimeoutException tex)
        {
            olog.outMensaje("cifxCliente.leerGuardarBytes(): Time out :"+tex.toString());
            return -1;
        } 
        catch (IOException ex) {
            //Logger.getLogger(cIfxClientesCon.class.getName()).log(Level.SEVERE, null, ex);
            olog.outMensaje("cifxCliente.leerGuardarBytes(): ERROR:"+ex.toString());
            return -1;
        }
        return nretorno;
    }
    /**
     * 
     * @param odatostemplate
     * @return
     */
    public String[] FENIXInsertar(caDatosTemplate odatostemplate)
    {
        return FENIXSolicitudes("FENIXInsertar","FENIX-Insertar",odatostemplate);
       
    }
    /**
     *
     * @param odatostemplate
     * @return
     */
    public String[] FENIXVerificar(caDatosTemplate odatostemplate)
    {
        return FENIXSolicitudes("FENIXVerificar","FENIX-Verificar",odatostemplate);
        
    }
    /***
     * Envia una solicitud de identificacion a un servidor aDirector
     * esta funcion es utilizada por un cliente para pedir una identificacion
     * a un servidor aDirector
     * @param odatostemplate *** caDatosTemplate con el template a identificar
     * @return *** Arreglo de String con las cedulas resultado
     */    
    public String[] FENIXIdentificar(caDatosTemplate odatostemplate)
    {
        return FENIXSolicitudes("FENIXIdentificar","FENIX-Identificar",odatostemplate);


    }

    /***
     * Esta funcion es utilizada para enviar una solicitud de identificacion a los diferentes AppsBots
     * Configurados en el sistema
     * La funcion es utilizada por la clase caAppBot para llamar la peticion de Identificacion.
     * 
     * Cliente->aDirector->AppBot
     *                   ->AppBot
     *                   ->AppBot
     * Puede cambiar...
     * @param odatostemplate objeto con los datos del template
     * @return un arreglo de strings con los resultados
     */
    private int respuestaSolBot=-9;//-9 Ejecutando accion
    //-2 ERROR Inesperado, -1 Transaccion no procesada, 0 Transaccion en TIME OUT, 1 Transaccion Ok
    public int getRespuestaSolApBot()
    {
        return respuestaSolBot;
    }
    public String[] botFENIXIdentificar(caDatosTemplate odatostemplate)
    {
        
        return FENIXSolicitudes("botFENIXIdentificar","botFENIX-Identificar",odatostemplate);

    }
    
     /***
     * Esta funcion es utilizada para enviar una solicitud de verificacion a los diferentes AppsBots
     * Configurados en el sistema
     * La funcion es utilizada por la clase caAppBot para llamar la peticion de Verificacion.
     * 
     * Cliente->aDirector->AppBot
     *                   ->AppBot
     *                   ->AppBot
     * Puede cambiar...
     * @param odatostemplate objeto con los datos del template
     * @return un arreglo de strings con los resultados
     */
    public String[] botFENIXVerificar(caDatosTemplate odatostemplate)
    {
        return FENIXSolicitudes("botFENIXVerificar","botFENIX-Verificar",odatostemplate);
        
    }
    /**
     * 
     * @param odatostemplate
     * @return
     */
    public String[] botFENIXInsertar(caDatosTemplate odatostemplate)
    {

        return FENIXSolicitudes("botFENIXInsertar","botFENIX-Insertar",odatostemplate);
    }
    
    /**
     * FUncion general de llamada de protocolo para FENIX
     * @param sfuncion
     * @param protoculo
     * @param odatostemplate
     * @return 
     */
        
//    private String[] FENIXSolicitudes(String sfuncion,String protoculo, caDatosTemplate odatostemplate)
//    {
//
//        String[] nrsalida=null;
//        if(!bconectado)
//            return null;
//        OutputStream sout;
//        //InputStream fin;
//        RandomAccessFile rfin;
//        BufferedReader brin;
//        String sentrada="";
//        boolean envioOK=false;
//
//
//        try {
//
//            olog.outMensaje(sfuncion+"(): SOLICITUD PARA:"+odatostemplate.aCadena());
//            sout = socket.getOutputStream();
//            brin = bin;//new BufferedReader(new InputStreamReader(socket.getInputStream()));
//
//            for(int i=0;i<odatostemplate.getNumTemplates();i++)
//            {
//                respuestaSolBot=-9;//-9 Ejecutando accion
//                sout.write((protoculo+" "+odatostemplate.aCadena()+"\n").getBytes());
//                sentrada=brin.readLine();
//
//                if(sentrada.equals(protoculo+" OK"))
//                {
//
//                    olog.outMensaje(sfuncion+"(): Servidor aDirector OK");
//
//                    String stmp="";
//                    sout.write(odatostemplate.getTemplate()[i].getTemplate(),0,
//                                    odatostemplate.getTemplate()[i].getTemplate().length);
//                    sout.flush();
//                    olog.outMensaje(sfuncion+"(): DATOS ENVIADOS :"+
//                            odatostemplate.getTemplate()[i].getTemplate().length);
//
//                    sentrada=brin.readLine();
//                    if(sentrada.equals(protoculo+" TRANSMISIONok"))
//                    {
//                        olog.outMensaje(sfuncion+"(): Template enviado y recibido por el servidor");
//                        olog.outMensaje(sfuncion+"(): Esperando pespuesta de la Identificacion ...");
//                        envioOK=true;
//
//                    }
//                    else
//                    {
//                        olog.outMensaje(sfuncion+"(): ERROR Template no se ha enviado al servidor");
//                        envioOK=false;
//
//                    }
//
//                }
//            }//CERRAR FOR
//
//            if(envioOK)
//            {
//
//                sentrada=brin.readLine();
//                if(sentrada.contains(protoculo+" RESPUESTA|"))
//                {
//                    sout.flush();
//                    olog.outMensaje(sfuncion+"(): TERMINO - "+sentrada);
//                    nrsalida= sentrada.split("|");
//
//                }
//                else
//                {
//                    olog.outMensaje(sfuncion+"(): ERROR EN EL SERVIDOR :"+sentrada);
//                    nrsalida= null;
//                }
//            }
//
//        }catch(SocketTimeoutException tex)
//        {
//            olog.outMensaje(sfuncion+"(): Time out :"+tex.toString());
//            respuestaSolBot=0;
//            nrsalida=null;
//            return null;
//
//        }
//
//        catch (Exception ex) {
//
//            olog.outMensaje(sfuncion+"(): ERROR Exception"+ex.toString());
//            respuestaSolBot=-2;
//            nrsalida=null;
//            return null;
//        }
//
//        if(nrsalida==null)
//        {
//            respuestaSolBot=-1;
//            return null;
//        }
//        else
//        {
//            String[] stmp = new String[nrsalida.length-1];
//            System.arraycopy(nrsalida, 1, stmp, 0, stmp.length);
//            respuestaSolBot=1;
//            return stmp;
//        }
//
//    }

    private String[] FENIXSolicitudes(String sfuncion,String protoculo, caDatosTemplate odatostemplate)
    {


        //Strail 28dic2011
        String[] nrsalida=null;
        if(!bconectado)
            return null;
        OutputStream sout;
        //InputStream fin;
        RandomAccessFile rfin;
        BufferedReader brin;
        String sentrada="";
        boolean envioOK=false;



        try {


            olog.outMensaje(sfuncion+"(): SOLICITUD PARA:"+odatostemplate.aCadena());
            sout = socket.getOutputStream();
            brin = bin;//new BufferedReader(new InputStreamReader(socket.getInputStream()));

            sout.write((protoculo+" "+odatostemplate.aCadena()+"\n").getBytes());
            sout.flush();

            for(int i=0;i<odatostemplate.getNumTemplates();i++)
            {
                respuestaSolBot=-9;//-9 Ejecutando accion


                sentrada=brin.readLine();


                if(sentrada.equals(protoculo+" OK"))
                {


                    olog.outMensaje(sfuncion+"(): Servidor aDirector OK");


                    String stmp="";
                    int len = odatostemplate.getTemplate()[i].getTemplate().length;


                    //Probando a enviar
                    sout.write(odatostemplate.getTemplate()[i].getTemplate(),0,len);
                    sout.flush();


                    olog.outMensaje(sfuncion+"(): DATOS ENVIADOS :"+
                            odatostemplate.getTemplate()[i].getTemplate().length);


                    sentrada=brin.readLine();
                    if(sentrada.equals(protoculo+" TRANSMISIONok"))
                    {
                        olog.outMensaje(sfuncion+"(): Template enviado y recibido por el servidor");
                        olog.outMensaje(sfuncion+"(): Esperando pespuesta de la Identificacion ...");
                        envioOK=true;


                    }
                    else
                    {
                        olog.outMensaje(sfuncion+"(): ERROR Template no se ha enviado al servidor");
                        envioOK=false;


                    }


                }
            }//CERRAR FOR


            if(envioOK)
            {

                sentrada=brin.readLine();
                if(sentrada.contains(protoculo+" RESPUESTA|"))
                {
                    //sout.flush();
                    olog.outMensaje(sfuncion+"(): TERMINO - "+sentrada);
                    nrsalida= sentrada.split("|");


                }
                else
                {
                    olog.outMensaje(sfuncion+"(): ERROR EN EL SERVIDOR :"+sentrada);
                    nrsalida= null;
                }
            }


        }catch(SocketTimeoutException tex)
        {
            olog.outMensaje(sfuncion+"(): Time out :"+tex.toString());
            respuestaSolBot=0;
            nrsalida=null;
            return null;


        }


        catch (Exception ex) {


            olog.outMensaje(sfuncion+"(): ERROR Exception"+ex.toString());
            respuestaSolBot=-2;
            nrsalida=null;
            return null;
        }


        if(nrsalida==null)
        {
            respuestaSolBot=-1;
            return null;
        }
        else
        {
            String[] stmp = new String[nrsalida.length-1];
            System.arraycopy(nrsalida, 1, stmp, 0, stmp.length);
            respuestaSolBot=1;
            return stmp;
        }


    }
    
}
